/*
* Copyright 2013 wada811<at.wada811@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package at.wada811.utils;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class GeoUtils {
public static final double WGS84_A = 6378137.000;
public static final double WGS84_E2 = 0.00669437999019758;
public static final double WGS84_MNUM = 6335439.32729246;
/**
* ヒュベニの公式 d = √( (dy * m)^2 + (dx * n * cos(my))^2 ) から2地点間の距離を算出する
*
* @param lat1 地点1の緯度
* @param lng1 地点1の軽度
* @param lat2 地点2の緯度
* @param lng2 地点2の軽度
* @return 2地点間の距離(m)
* @see <a href="http://yamadarake.jp/trdi/report000001.html">二地点の緯度・経度からその距離を計算する(日本は山だらけ〜)</a>
* @licenses MIT License
*/
public static double calcDistance(double lat1, double lng1, double lat2, double lng2){
double my = Math.toRadians((lat1 + lat2) / 2.0);
double dy = Math.toRadians(lat1 - lat2);
double dx = Math.toRadians(lng1 - lng2);
double sin = Math.sin(my);
double w = Math.sqrt(1.0 - WGS84_E2 * sin * sin);
double m = WGS84_MNUM / (w * w * w);
double n = WGS84_A / w;
double dym = dy * m;
double dxncos = dx * n * Math.cos(my);
return Math.sqrt(dym * dym + dxncos * dxncos);
}
/**
* ミリ秒形式から度分秒形式に変換する
*
* ミリ秒→秒: /1000
* 秒→分: /60
* 分→度: /60
*
* @param milliseconds ミリ秒形式の緯度・経度
* @return 度分秒形式の緯度・経度
*/
public static double toDegree(double milliseconds){
return milliseconds / 3600000;
}
/**
* 度分秒形式からミリ秒形式に変換する
*
* 度→分: *60
* 分→秒: *60
* 秒→ミリ秒: *1000
*
* @param degree 度分秒形式の緯度・経度
* @return ミリ秒形式の緯度・経度
*/
public static double toMillisecond(double degree){
return degree * 3600000;
}
/**
* 緯度経度から {@link Address} のリストを取得する
*
* @param context
* @param latitude 緯度
* @param longitude 軽度
* @param maxResults 1-5, Set 1 when passing less than 1 and set 5 when passing greater than 5
* @return address list
*/
public static List<Address> getAddressList(Context context, double latitude, double longitude, int maxResults){
if(latitude < -90.0 || latitude > 90.0){
return new ArrayList<Address>();
}
if(longitude < -180.0 || longitude > 180.0){
return new ArrayList<Address>();
}
if(maxResults < 1){
maxResults = 1;
}else if(maxResults > 5){
maxResults = 5;
}
Geocoder geocoder = new Geocoder(context);
try{
return geocoder.getFromLocation(latitude, longitude, maxResults);
}catch(IOException e){
e.printStackTrace();
return new ArrayList<Address>();
}
}
/**
* 緯度経度から {@link Address} を取得する
*
* @param context
* @param latitude 緯度
* @param longitude 軽度
* @return address
*/
public static Address getAddress(Context context, double latitude, double longitude){
List<Address> addressList = GeoUtils.getAddressList(context, latitude, longitude, 1);
if(addressList.isEmpty()){
return null;
}else{
return addressList.get(0);
}
}
}